/*
<div id="app" style="color: red; font-size: 20px">
  你好, {{ name }}
  <span class="text" style="color: green">{{ age }}</span>
</div>

// 创建元素
_c()  => createElement()
// 创建文本节点
_v()  => createTextNode()
// 处理 {{}}
_s()  => {{name}} =>  _s(name)

// 上面的 html 最终应该解析成如下结构
function render () {
  return `
    _c(
      "div",
      {
        id: "app",
        style: {
          "color": "red",
          "font-size": "20px"
        }
      },
      _v("你好，" + _s(name),
      _c(
        "span",
        {
          class: "text",
          style: {
            color: "green"
          }
        },
        _v(_s(age))
      )
    )
  `
}
*/

// 用于匹配 {{}}
const defaultTagRe = /\{\{((?:.|\r?\n)+?)\}\}/g;

function formatProps(attrs) {
  let attrStr = ''

  for (let i = 0, len = attrs.length; i < len; i++) {
    const attr = attrs[i]
    if (attr.name === 'style') {
      const styleAttrs = {}
      attr.value.split(';').map(styleAttr => {
        const [key, value] = styleAttr.split(':')
        styleAttrs[key] = value
      })
      attr.value = styleAttrs
    }
    attrStr += `${attr.name}: ${JSON.stringify(attr.value)},`
  }

  // {id: "app",style: {"color":" red"," font-size":" 20px"}}
  return `{${attrStr.slice(0, -1)}}`
}

const ELEMENT_TAG_TYPE = 1
const TEXT_TAG_TYPE = 3
function generateChildren (node) {
  if (node.type === ELEMENT_TAG_TYPE) {
    return generate(node)
  }
  if (node.type === TEXT_TAG_TYPE) {
    const text = node.text

    // 匹配非 {{}}
    if (!defaultTagRe.exec(text)) {
      return `_v(${JSON.stringify(text)})`
    }

    // 将   
    // 你好, {{ name }} 欢迎学习 vue
    // 转换为
    // _v("你好，" + _s(name) + " 欢迎学习 vue",
    let match,
        index,
        lastIndex = defaultTagRe.lastIndex = 0,
        textArr = []
    while(match = defaultTagRe.exec(text)) {
      index = match.index

      if (index > lastIndex) {
        textArr.push(JSON.stringify(text.slice(lastIndex, index)))
      }
      textArr.push(`_s(${match[1].trim()})`)
      lastIndex = index + match[0].length
    }

    if (lastIndex < text.length) {
      textArr.push(JSON.stringify(text.slice(lastIndex)))
    }

    return `_v(${textArr.join('+')})`
  }
}

function getChildren (children) {
  if (children) {
    return children.map(c => generateChildren(c)).join(',')
  }
}

export function generate (ast) {
  const children = getChildren(ast.children)

  const code = `_c('${ast.tag}',${
    ast.attrs.length > 0
    ? `${formatProps(ast.attrs)}`
    : 'undefined'
  }${
    children ? `,${children}` : ''
  })`

  return code
}

// code 最终的内容为：
// _c('div',{id: "app",style: {"color":" red"," font-size":" 20px"}},_v("你好, "+_s(name)+" 欢迎学习 vue"),_c('span',{class: "text",style: {"color":" green"}},_v(_s(age))),_c('p',undefined,_v("学习 vue 源码")))